'''
Created on Sep 20, 2009

@author: jafd
'''

import expressions

class SQLDialect(object):
    
    def translateLiteral(self, expression):
        if isinstance(expression.value, int) or \
            isinstance(expression.value, float):
            return str(expression.value)
        else:
            return "'" + str(expression.value).replace("'", "\\'") + "'"
        
    def translateAttributeName(self, expression):
        return ".".join(map(str, expression.value))

    def translateExpressionList(self, expression):
        return ", ".join(map(str, expression.value))

    def translateExpressionGroup(self, expression):
        if(expression.value == None):
            return "()"
        else:
            return "(" + str(expression.value) + ")"
        
    def translateFunction(self, expression):
        return str(expression.operation).upper() + str(expression.value)
    
    def translateBinaryExpression(self, expression):
        return " ".join((str(expression.lvalue), str(expression.operation), 
            str(expression.rvalue)))

    def translateExpression(self, expression):
        return expression.value
    
    def translate(self, expression):
        if not isinstance(expression, expressions.Expression):
            raise TypeError, "Cannot translate non-expressions!"
        c = expression.__class__.__name__
        si = expression
        meth = 'translate' + c
        while (not hasattr(self, meth)):
            #
            # TODO: improve the algorithm to work with multiple bases!
            #
            si = si.__class__.__bases__[0]
            c = si.__class__.__name__
            meth = 'translate' + c
        if not hasattr(self, meth) or not callable(getattr(self, meth)):
            raise NotImplementedError, "This dialect does not support expressions of type %s" % expression.__class__.__name__
        return self.__getattribute__(meth)(expression)

class MySQLDialect(SQLDialect):
    def translateAttributeName(self, expression):
        return ".".join(map(lambda(x): '`' + str(x) + '`', expression.value))
    
class Dialect(object):
    def __new__(self, *args):
        return SQLDialect()

